const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
  /**
   * Promise 构造函数
   * @param {Function} executor - 执行器函数，接收 resolve 和 reject 两个参数
   *                             (resolve: Function, reject: Function) => void
   */
  constructor(executor) {
    // 初始化 Promise 状态和值
    this.state = PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = []; // 成功状态回调队列
    this.onRejectedCallbacks = []; // 拒绝状态回调队列

    /**
     * 状态转换到 fulfilled 的核心方法
     * @param {any} value - 传递给 then 方法的参数值
     *                      支持处理 thenable 对象和普通值
     */
    const resolve = (value) => {
      if (this.state === PENDING) {
        // 处理 thenable 对象（符合 Promise/A+ 规范的解决过程）
        if (
          value !== null &&
          (typeof value === "object" || typeof value === "function")
        ) {
          try {
            const then = value.then;
            if (typeof then === "function") {
              // 递归解析 thenable 对象
              then.call(
                value,
                (newValue) => resolve(newValue), // 新值继续递归解析
                (newReason) => reject(newReason) // 传递拒绝原因
              );
              return;
            }
          } catch (e) {
            reject(e); // 捕获 then 方法执行异常
            return;
          }
        }

        // 状态转移和回调触发
        this.state = FULFILLED;
        this.value = value;
        this.onFulfilledCallbacks.forEach((cb) => cb()); // 触发所有成功回调
      }
    };

    /**
     * 状态转换到 rejected 的核心方法
     * @param {any} reason - 传递给 catch 方法的错误原因
     */
    const reject = (reason) => {
      if (this.state === PENDING) {
        this.state = REJECTED;
        this.reason = reason;
        this.onRejectedCallbacks.forEach((cb) => cb()); // 触发所有拒绝回调
      }
    };
    // 执行用户传入的 executor
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error); // 捕获同步执行错误
    }
  }
  /**
   * Promise的then方法实现，遵循Promises/A+规范
   * @param {Function} [onFulfilled] - 可选参数，当Promise兑现时的回调函数
   * @param {Function} [onRejected] - 可选参数，当Promise拒绝时的回调函数
   * @returns {MyPromise} 返回新Promise对象，支持链式调用
   */
  then(onFulfilled, onRejected) {
    // 参数标准化处理：确保回调始终为函数类型
    // 当onFulfilled未提供时，创建默认穿透函数 v => v
    // 当onRejected未提供时，创建默认抛出函数 e => { throw e }
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (e) => {
            throw e;
          };

    // 创建新Promise用于实现链式调用
    const promise2 = new MyPromise((resolve, reject) => {
      // 处理成功状态的统一方法
      const handleFulfilled = () => {
        // 使用微任务队列保证异步执行
        queueMicrotask(() => {
          try {
            // 执行成功回调并处理返回值
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            // 捕获同步异常并拒绝promise2
            reject(e);
          }
        });
      };

      // 处理拒绝状态的统一方法
      const handleRejected = () => {
        // 使用微任务队列保证异步执行
        queueMicrotask(() => {
          try {
            // 执行失败回调并处理返回值
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            // 捕获同步异常并拒绝promise2
            reject(e);
          }
        });
      };

      // 状态机处理逻辑
      if (this.state === FULFILLED) {
        // 当前状态已兑现，立即执行处理
        handleFulfilled();
      } else if (this.state === REJECTED) {
        // 当前状态已拒绝，立即执行处理
        handleRejected();
      } else {
        // 等待状态，将处理函数存入回调队列
        this.onFulfilledCallbacks.push(handleFulfilled);
        this.onRejectedCallbacks.push(handleRejected);
      }
    });

    return promise2;
  }

  catch(onRejected) {
    return this.then(null, onRejected);
    /**
     * 注册 Promise 拒绝状态的回调函数（catch 语法糖方法）
     *
     * 实现原理：通过调用 then 方法，传入拒绝回调作为第二个参数。
     * 相当于 .then(undefined, onRejected) 的语法糖形式
     *
     * @param {Function} onRejected - 拒绝状态回调函数
     *     参数格式：(reason) => any | newValue
     *     @param {Error} reason - 拒绝原因（通常是 Error 对象）
     *     @returns {any} 将作为新 Promise 的决议值
     *
     * @returns {Promise} 返回新 Promise 对象，其状态由以下决定：
     *     - 若 onRejected 正常返回：变为 fulfilled 状态，值为返回值
     *     - 若 onRejected 抛出异常：变为 rejected 状态，值为异常对象
     */
  }

  /**
   * Promise.prototype.finally 的实现，无论原始Promise状态如何都会执行回调
   * @param {Function} callback - 要执行的回调函数（无参数，忽略其返回值）
   * @returns {MyPromise} 返回新的Promise实例：
   * 1. 会等待回调函数执行完成（若回调返回Promise则等待其完成）
   * 2. 最终会传递原始Promise的决议值或拒绝原因
   */
  finally(callback) {
    // 通过 then 方法同时处理 fulfilled 和 rejected 状态
    return this.then(
      // 成功状态处理：执行回调后传递原始值
      (value) => MyPromise.resolve(callback()).then(() => value),
      // 失败状态处理：执行回调后重新抛出原因
      (reason) =>
        MyPromise.resolve(callback()).then(() => {
          throw reason;
        })
    );
  }

  /**
   * 创建已解决的Promise实例
   * 实现Promise解析规则：当参数是Promise实例时直接返回，否则创建新Promise并立即解决
   * @param {any} value - 要解析的值，可以是普通值、thenable对象或Promise实例
   * @returns {MyPromise} 已解决的Promise实例
   */
  static resolve(value) {
    // 处理传入值本身就是Promise实例的情况（避免多余的Promise包装）
    if (value instanceof MyPromise) {
      return value;
    }

    // 创建立即进入fulfilled状态的新Promise
    // 注意：这里隐含执行了Promise的解析过程（处理thenable对象的情况）
    return new MyPromise((resolve) => {
      resolve(value);
    });
  }

  /**
   * 创建一个立即拒绝的 MyPromise 实例
   * @static
   * @param {*} reason - 拒绝原因，建议使用 Error 对象以便保留调用栈信息
   * @returns {MyPromise} 已拒绝的 Promise 对象
   *
   * 实现原理：
   * - 通过立即执行器函数同步执行拒绝操作
   * - 保持与原生 Promise.reject() 一致的行为特征
   */
  static reject(reason) {
    return new MyPromise((_, reject) => {
      reject(reason);
    });
  }
}

/**
 * 解决Promise的解析过程，遵循Promises/A+规范实现
 * @param {MyPromise} promise2 - 需要被解析的目标Promise实例
 * @param {*} x - 待解析的值，可能是普通值/Promise/thenable对象
 * @param {Function} resolve - 外部传入的完成回调函数
 * @param {Function} reject - 外部传入的拒绝回调函数
 * @returns {void} 无直接返回值，通过回调函数传递结果
 */
function resolvePromise(promise2, x, resolve, reject) {
  // 处理循环引用检测（规范2.3.1）
  if (promise2 === x) {
    reject(new TypeError("Chaining cycle detected for promise"));
    return;
  }

  // 处理MyPromise实例的递归解析（规范2.3.2）
  if (x instanceof MyPromise) {
    x.then((value) => resolvePromise(promise2, value, resolve, reject), reject);
    return;
  }

  // 处理thenable对象（规范2.3.3）
  if (x !== null && (typeof x === "object" || typeof x === "function")) {
    let then;

    // 安全获取then属性的try-catch块（规范2.3.3.2）
    try {
      then = x.then;
    } catch (e) {
      reject(e);
      return;
    }

    // 处理真实thenable对象（规范2.3.3.3）
    if (typeof then === "function") {
      let called = false; // 保证单次调用的防御标志

      try {
        // 执行then方法并处理回调
        then.call(
          x,
          (y) => {
            // 递归解析y值（规范2.3.3.3.1）
            if (called) return;
            called = true;
            resolvePromise(promise2, y, resolve, reject);
          },
          (r) => {
            // 直接拒绝的路径（规范2.3.3.3.2）
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } catch (e) {
        // 处理then执行时的异常（规范2.3.3.3.4）
        if (!called) {
          reject(e);
        }
      }
    } else {
      // 处理普通对象（规范2.3.3.4）
      resolve(x);
    }
  } else {
    // 处理基础类型值（规范2.3.4）
    resolve(x);
  }
}

/**
 * 创建并返回一个包含 Promise 控制权的延迟对象
 * (静态方法，用于实现 Promises/A+ 测试规范)
 *
 * @returns {Object} 延迟对象包含以下属性：
 *   - promise: MyPromise 实例对象
 *   - resolve: 用于解决关联 promise 的函数
 *   - reject: 用于拒绝关联 promise 的函数
 */
MyPromise.deferred = function () {
  // 创建空容器对象，后续将挂载 promise 及其控制器
  const result = {};

  // 创建新的 promise 实例，同时暴露其控制权到容器对象
  result.promise = new MyPromise((resolve, reject) => {
    // 将 promise 的决议权绑定到容器对象
    result.resolve = resolve;
    result.reject = reject;
  });

  return result;
};

module.exports = MyPromise;
